package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
@Slf4j
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    private ApplicationMapper applicationMapper;


    @Override
    public void insertAudit(Application application) {
        log.debug("根据申请生成对应审批数据业务：{}"+application);
        //1.获取审批人id集合
        List<Long> userIdList = application.getAuditUserIdList();
        //2.遍历集合，为每个遍历道德审批人生成审批数据
        for (int i= 0;i<userIdList.size();i++){
            Audit audit = new Audit();//3.创建空对象用来封装新增条件
            audit.setApplicationId(application.getId());//设置审批哪个申请单
            audit.setAuditUserId(userIdList.get(i));//设置审批人id
            audit.setAuditSort(i);//设置审批次序
            if (i==0){//如果是第一个审批人
                audit.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());//待我审核
        }else {
                audit.setAuditStatus(AuditStatusEnum.PENGDING.getCode());//待他人审核
            }
            audit.setCreateTime(new Date());//设置创建时间
            auditMapper.insert(audit);//审批数据入库
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        log.debug("根据申请单id查询审批单数据业务：{}"+id);
        return auditMapper.selectAuditByApplicationId(id);
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批数据业务：{}",auditQuery);
        List<AuditVO> list = auditMapper.selectAudit(auditQuery);
        for (int i=0;i<list.size();i++){
            AuditVO auditVO = list.get(i);
            assignAuditUserList(auditVO);
        }
        return list;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("审批申请单业务:{}",auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit);
        audit.setUpdateTime(new Date());
        //先更新自己的这条审批单数据
        auditMapper.update(audit);
        //准备当前审批的这条申请单数据，更新申请单
        Application application = new Application();
        application.setId(auditSaveParam.getApplicationId());
        application.setUpdateTime(new Date());
        /* 需要判断是通过还是驳回，分别处理 */
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){ //审批通过
            //继续查审批单：统计当前审批单对应的所有未审批的审批单总数
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            if (count > 0){//还有未审批的审批单
                //继续封装查询条件，将后面那条审批单查出来
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                if (auditVOList !=null && auditVOList.size()> 0){
                    AuditVO auditVO = auditVOList.get(0);
                    //创建第2个实体类对象，更新第二条审批单
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());
                    audit2.setUpdateTime(new Date());
                    auditMapper.update(audit2);
                }
                //还要更新申请单为“审核中”
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            }else {//没有未审批的审批单了，刚刚更新的审批单就是最后一条审批单
                //设置申请单的状态为“已审核"，后续可以分配车辆了
                application.setStatus(AuditStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        }else {//审批驳回
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            //判断集合是否为空
            if (auditVOList != null && auditVOList.size()>0){
                for (int i=0;i<auditVOList.size();i++){
                AuditVO auditVO = auditVOList.get(i);
                if (auditVO.getAuditSort().equals(AuditStatusEnum.PENGDING.getCode())){
                    auditMapper.deleteById(auditVO.getId());
            }
        }
                //还需要设置申请单的状态为“已驳回”，并设置驳回原因
                application.setStatus(ApplicationStatusEnum.REJECT.getCode());
                application.setRejectReason(auditSaveParam.getRejectReason());
                applicationMapper.update(application);
            }
        }
    }

    private void assignAuditUserList(AuditVO auditVO){
        List<Long> auditUserIdList = new ArrayList<>();
        List<String> auditUsernameList = new ArrayList<>();
        //根据传入的审批单VO中的申请单id，查到申请单对应的所有审批单
        List<AuditVO> auditVOList = auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //遍历审批单集合，依次取出每个审批单，以及审批单中的审批人id
        for (int i=0;i<auditVOList.size();i++){
            Long userId = auditVOList.get(i).getAuditUserId();
            auditUserIdList.add(userId);
            UserVO userVO = userMapper.selectById(userId);
            auditUsernameList.add(userVO.getUsername());
        }
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList){
            stringJoiner.add(username);
        }
        auditVO.setAuditUserIdList(auditUserIdList);
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }
}
